package com.studymaster.util;

import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;


public final class JsonHelper {
    // Constant values
    public static final int     ERROR_INTEGER = 0;
    public static final double  ERROR_DOUBLE  = 0f;
    public static final boolean ERROR_BOOLEAN = false;
    private static Gson mGson;

    private JsonHelper() {}

    /**
     * Load
     * 
     * @param json
     *            JSON string who contains JSON text
     * @return
     */
    public static JSONObject loadJSON( String aJsonString ) {
        try {
            if ( aJsonString != null && aJsonString.length() != 0 ) {
                return new JSONObject( aJsonString );
            }
        }
        catch ( JSONException e ) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Get integer from JSON object
     * 
     * @param aJoObj
     * @param aName
     * @return
     */
    public static int getInt( JSONObject aJoObj, String aName ) {
        try {
            if ( aJoObj != null && aJoObj.has( aName ) ) {
                return aJoObj.getInt( aName );
            }
        }
        catch ( JSONException e ) {
            e.printStackTrace();
        }
        return ERROR_INTEGER;
    }

    /**
     * Get long from JSON object
     * 
     * @param aJoObj
     * @param aName
     * @return
     */
    public static long getLong( JSONObject aJoObj, String aName ) {
        try {
            if ( aJoObj != null && aJoObj.has( aName ) ) {
                return aJoObj.getLong( aName );
            }
        }
        catch ( JSONException e ) {
            e.printStackTrace();
        }
        return ERROR_INTEGER;
    }

    /**
     * Get string from JSON object
     * 
     * @param aJoObj
     * @param aName
     * @return
     */
    public static String getString( JSONObject aJoObj, String aName ) {
        try {
            if ( aJoObj != null && aJoObj.has( aName ) ) {
                String value = aJoObj.getString( aName );
                if ( !value.equals( JSONObject.NULL ) ) {
                    return value;
                }
            }
        }
        catch ( JSONException e ) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Get boolean from JSON object
     * 
     * @param aJoObj
     * @param aName
     * @return
     */
    public static boolean getBoolean( JSONObject aJoObj, String aName ) {
        try {
            if ( aJoObj != null && aJoObj.has( aName ) ) {
                return aJoObj.getBoolean( aName );
            }
        }
        catch ( JSONException e ) {
            e.printStackTrace();
        }
        return ERROR_BOOLEAN;
    }

    /**
     * Get double from JSON object
     * 
     * @param aJoObj
     * @param aName
     * @return
     */
    public static double getDouble( JSONObject aJoObj, String aName ) {
        try {
            if ( aJoObj != null && aJoObj.has( aName ) ) {
                return aJoObj.getDouble( aName );
            }
        }
        catch ( JSONException e ) {
            e.printStackTrace();
        }
        return ERROR_DOUBLE;
    }

    /**
     * Get sub object from JSON object
     * 
     * @param aJoObj
     * @param aName
     * @return
     */
    public static JSONObject getJSONObject( JSONObject aJoObj, String aName ) {
        try {
            if ( aJoObj != null && aJoObj.has( aName ) ) {
                return aJoObj.getJSONObject( aName );
            }
        }
        catch ( JSONException e ) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Get sub JSON array from JSON object
     * 
     * @param aJoObj
     * @param aName
     * @return
     */
    public static JSONArray getJSONArray( JSONObject aJoObj, String aName ) {
        try {
            if ( aJoObj != null && aJoObj.has( aName ) ) {
                return aJoObj.getJSONArray( aName );
            }
        }
        catch ( JSONException e ) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Get the length of a JSON array
     * 
     * @param aJoArray
     * @return
     */
    public static int getArrayLength( JSONArray aJoArray ) {
        if ( aJoArray != null ) {
            return aJoArray.length();
        }
        return 0;
    }

    /**
     * Get JSON object from JSON array
     * 
     * @param aJoArray
     * @param aIndex
     * @return
     */
    public static JSONObject getJSONObject( JSONArray aJoArray, int aIndex ) {
        try {
            if ( aJoArray != null && !aJoArray.isNull( aIndex ) ) {
                return aJoArray.getJSONObject( aIndex );
            }
        }
        catch ( JSONException e ) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Get string from JSON array
     * 
     * @param aJoArray
     * @param aIndex
     * @return
     */
    public static String getStringFromArray( JSONArray aJoArray, int aIndex ) {
        try {
            if ( aJoArray != null && !aJoArray.isNull( aIndex ) ) {
                String value = aJoArray.getString( aIndex );
                if ( !value.equals( JSONObject.NULL ) ) {
                    return value;
                }
            }
        }
        catch ( JSONException e ) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Get integer from JSON array
     * 
     * @param aJoArray
     * @param aIndex
     * @return
     */
    public static int getIntFromArray( JSONArray aJoArray, int aIndex ) {
        try {
            if ( aJoArray != null && !aJoArray.isNull( aIndex ) ) {
                return aJoArray.getInt( aIndex );
            }
        }
        catch ( JSONException e ) {
            e.printStackTrace();
        }
        return ERROR_INTEGER;
    }

    /**
     * Get boolean from JSON array
     * 
     * @param aJoArray
     * @param aIndex
     * @return
     */
    public static boolean getBoolFromArray( JSONArray aJoArray, int aIndex ) {
        try {
            if ( aJoArray != null && !aJoArray.isNull( aIndex ) ) {
                return aJoArray.getBoolean( aIndex );
            }
        }
        catch ( JSONException e ) {
            e.printStackTrace();
        }
        return ERROR_BOOLEAN;
    }

    public static Object getClass( String json, Class<?> classOfT ){
    	if ( mGson == null ){
    		mGson = new Gson();
    	}
    	Object o = null;
    	
    	try{
    		o = mGson.fromJson(json, classOfT);
    	}catch(JsonSyntaxException e){
    		
    	}
    	
    	return o;
    }
    
    public static <T> List<T> getClassList( String json ){
    	if ( mGson == null ){
    		mGson = new Gson();
    	}
    	
    	List<T> o = new ArrayList<T>();
    	
    	try{
    		o = mGson.fromJson(json, new TypeToken<List<T>>() {  
            }.getType()); 
    	}catch(JsonSyntaxException e){
    		
    	}
    	
    	return o;
    }
    
    public static String ToJson(Object o){
    	if ( mGson == null ){
    		mGson = new Gson();
    	}
    	String json = "";
    	
    	json = mGson.toJson(o);
    	
    	return json;
    }
}
